package websocket.listener;

import gnu.io.SerialPortEvent;
import gnu.io.SerialPortEventListener;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import websocket.entity.vo.SerialPortVo;
import websocket.service.ChuanKouService;
import websocket.util.ComBeanUtil4G;
import websocket.util.ConfigProperties;
import websocket.util.DigitalTrans;

import java.io.UnsupportedEncodingException;
import java.util.Map;

//import static websocket.controller.ConnectionManageController.portMap;

/**
 * Created by zsc on 2017/5/9.
 */
public abstract class PortListener implements SerialPortEventListener {

    final Logger logger = LoggerFactory.getLogger(PortListener.class);
    private final Map<String, String> map = new ConfigProperties().getPropertiesMap("application.yml");
    protected SerialPortVo serialPortVo;
    protected int sleepTime;

    public void setSleepTime(int sleepTime) {
        this.sleepTime = sleepTime;
    }

    public void setSerialPort(SerialPortVo serialPortVo) {
        this.serialPortVo = serialPortVo;
    }

    @Override
    public void serialEvent(SerialPortEvent serialPortEvent) {
        switch (serialPortEvent.getEventType()) {
            case SerialPortEvent.BI: // 10 通讯中断
                logger.error("与串口设备通讯中断");
                break;
            case SerialPortEvent.OE: // 7 溢位（溢出）错误
                logger.error("溢位（溢出）错误");
                break;
            case SerialPortEvent.FE: // 9 帧错误
                logger.error("帧错误");
                break;
            case SerialPortEvent.PE: // 8 奇偶校验错误
            case SerialPortEvent.CD: // 6 载波检测
            case SerialPortEvent.CTS: // 3 清除待发送数据
            case SerialPortEvent.DSR: // 4 待发送数据准备好了
            case SerialPortEvent.RI: // 5 振铃指示
            case SerialPortEvent.OUTPUT_BUFFER_EMPTY: // 2 输出缓冲区已清空
                break;
            case SerialPortEvent.DATA_AVAILABLE: // 1 串口存在可用数据
                try {
                    // 延时收到字符串一段时间，足够接收所有字节，以免出现字符串隔断
                    Thread.sleep(sleepTime);
                    byte[] data = null;
                    if (serialPortVo.getSerialPort() == null) {
                        logger.error("\n串口对象为空！监听失败！");
                    } else {
                        // 航向信息串口号
                        String hangXiangPort = map.get("hangXiangPort");
//                        String hangXiangPort =  portMap.get("cldPort");
                        // 航向帧头/最佳位置帧头
                        String hangXiangZhenTou = map.get("hangXiangZhenTou");
                        // 水平仪串口号
                        String horizontalPort = map.get("horizontalPort");
                        // 水平仪帧头
                        String horizontalZhenTou = map.get("horizontalZhenTou");
                        // 双轴转台串口号
                        String shuangZhouZhuanTaiPort = map.get("shuangZhouZhuanTaiPort");
                        // 双轴转台帧头
                        String shuangZhouZhuanTaiZhenTou = map.get("shuangZhouZhuanTaiZhenTou");
                        // 无人机串口号
                        String wuRenJiPort = map.get("wuRenJiPort");
                        // 无人机名称
                        String wuRenJiZhenTou = map.get("wuRenJiZhenTou");
                        // 截取串口号
                        String port = subPort(serialPortVo.getSerialPort().toString());
//                        logger.info("读取【application.yml】的配置【航向串口：" + hangXiangPort + "】【水平仪串口：" + horizontalPort + "】【双轴转台串口：" + shuangZhouZhuanTaiPort + "】");
//                         TODO 待放开
                          data = serialPortVo.readData();
//                        data = ComBeanUtil4G.getMap(8091);
//                        String needData = DigitalTrans.printHexString(data);
//                        ChuanKouService.chuLiChuanKouHorizontalData(needData, horizontalZhenTou);

                        if (data == null) {
                            return;
                        }
                        // 判断当前是哪个串口的数据 待放开 TODO
                        String needData = DigitalTrans.printHexString(data);
                        if (port.equals(hangXiangPort)) {
                            // 航向数据
                            ChuanKouService.chuLiChuanKouHangXiangData(needData, hangXiangZhenTou);
                        } else if (port.equals(horizontalPort)) {
                            // 测量点数据
                            ChuanKouService.chuLiChuanKouHorizontalData(needData, horizontalZhenTou);
                        } else if (port.equals(shuangZhouZhuanTaiPort)) {
                            // 双轴转台
                            ChuanKouService.chuliShuangZhouZhuanTaiData(needData, shuangZhouZhuanTaiZhenTou);
                        } else if (port.equals(wuRenJiPort)) {
                            // 无人机
                            ChuanKouService.chuliWuRenJiData(needData, wuRenJiZhenTou);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    logger.error("【串口监听】" + e.getMessage());
//                    onReadException(e);
                }
                break;
        }
    }

    /**
     * 串口号截取
     *
     * @param port
     */
    protected String subPort(String port) {
        // 判断当前字节是几位
        if (port.length() == 8) {
            // 例如：port为：//./COM1   所以要判断截取COM1
            port = port.substring(4, 8);
        } else if (port.length() == 9) {
            // 例如：port为：//./COM11   所以要判断截取COM11
            port = port.substring(4, 9);
        }
        return port;
    }

    abstract public void onReadException(Exception e);

    abstract public void onReceive(byte[] data) throws UnsupportedEncodingException;
}
